package easypal.brilliard.world.brilliards.communication.impl;

import java.util.ArrayList;
import java.util.List;

import easypal.brilliard.util.TraceUtil;
import easypal.brilliard.world.brilliards.communication.CommunicationAgent;
import easypal.brilliard.world.brilliards.communication.CommunicationChannel;
import easypal.brilliard.world.brilliards.communication.CommunicationException;
import easypal.brilliard.world.brilliards.communication.CommunicationReceiver;

public class CommunicationAgentImpl implements CommunicationAgent {
	protected boolean isDestroyed;
	
	protected CommunicationChannel communicationChannel;
	protected List<CommunicationReceiver> communicationReceivers = new ArrayList<CommunicationReceiver>(2);

	
	/* I rarely write three constructors. */
	public CommunicationAgentImpl() {
		
	}
	public CommunicationAgentImpl(CommunicationChannel channel) {
		this.communicationChannel = channel;
	}
	public CommunicationAgentImpl(CommunicationChannel channel,
			CommunicationReceiver receiver) {
		
		this.communicationChannel = channel;
		this.communicationReceivers.add(receiver);
	
	}
	
	@Override
	public void init() {
		this.isDestroyed = false;
	}
	
	@Override
	public void destory() {
		this.isDestroyed = true;
		
		if (this.communicationChannel != null) this.communicationChannel.destroy();
		communicationChannel = null;
		
		communicationReceivers.clear();
	}
	
	@Override
	public void send(String message) throws CommunicationException {
		//if (this.communicationChannel != null) {
			this.communicationChannel.send(message);
		//}
		TraceUtil.trace(this, "Send message: " + "|"+message+"|");
	}
	
	@Override
	public CommunicationChannel getChannel() {
		return this.communicationChannel;
	}

	@Override
	public void setChannel(CommunicationChannel cc) {
		this.communicationChannel = cc;
		
	}


	@Override
	public void addReceiver(CommunicationReceiver cr) {
		this.communicationReceivers.add(cr);
		
	}

	@Override
	public List<CommunicationReceiver> getReceivers() {
		return this.communicationReceivers;
	}

	@Override
	public void run() {
		String message;
		
		while (!isDestroyed) {
			try {
				message = this.communicationChannel.receive();
			} catch (CommunicationException ex) {
				message = null;
				throw new RuntimeException("communication agent receiving message fails", ex);
			}
			
			try {
				for (CommunicationReceiver r : this.communicationReceivers) {
					r.received(this, message);
				}
			} catch (CommunicationException ex) {
				throw new RuntimeException("communication receiver handling message fails,", ex);
			}
			
		}
	}

}
